﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
using M3G;

namespace MyTestProject {

    public class TestWorld {
        [Fact]
        public void TestConstructor () {
            var wld = new World ();

            Assert.Equal (null, wld.ActiveCamera);
            Assert.Equal (null, wld.Background);
        }

        [Fact]
        public void TestSetActiveCamera () {
            var wld = new World ();
            var cam = new Camera ();
            wld.SetActiveCamera (cam);

            Assert.Equal (cam, wld.ActiveCamera);
        }

        [Fact]
        public void TestSetBackground () {
            var bg  = new Background ();
            var wld = new World ();
            wld.SetBackground (bg);

            Assert.Equal (bg, wld.Background);
        }

        [Fact]
        public void TestReferences () {
            var bg  = new Background ();
            var cam = new Camera ();
            var wld = new World ();
            wld.SetBackground (bg);
            wld.SetActiveCamera (cam);

            var refs = wld.References;

            Assert.Equal (2, refs.Length);
            Assert.Same (bg, wld.Background);
            Assert.Same (cam, wld.ActiveCamera);
        }

        /**
         * Findがシーングラフ全体を検索していることを確認するテスト
         * 実は冗長だがよりユーザーの使用例に近い形でテストを行っている
         * */
        [Fact]
        public void TestFind () {
            var wld = new World ();
            var node1  = new Group ();
            var node2  = new Light ();
            var keyseq = new KeyframeSequence (4, 3, KeyframeSequence.Step);
            var track  = new AnimationTrack (keyseq, AnimationTrack.Color);
            var ctrl   = new AnimationController ();

            wld.AddChild (node1);
            node1.AddChild (node2);
            node2.AddAnimationTrack (track);
            track.SetController (ctrl);
         
            wld.UserID = 100;
            node1.UserID = 101;
            node2.UserID = 102;
            ctrl.UserID = 103;
            keyseq.UserID = 104;
            track.UserID = 105;

            Assert.Equal (wld, wld.Find (100));
            Assert.Equal (node1, wld.Find (101));
            Assert.Equal (node2, wld.Find (102));
            Assert.Equal (ctrl, wld.Find (103));
            Assert.Equal (keyseq, wld.Find (104));
            Assert.Equal (track, wld.Find (105));
        }

        /**
          * FindAll<T>()がシーングラフ全体を検索していることを確認するテスト
          * 実は冗長だがよりユーザーの使用例に近い形でテストを行っている
          * */
        [Fact]
        public void TestFindAll () {
            var wld    = new World ();
            var node1  = new Group ();
            var node2  = new Light ();
            var keyseq = new KeyframeSequence (4, 4, 1, KeyframeSequence.Step);
            var track1 = new AnimationTrack (keyseq, AnimationTrack.Alpha);
            var track2 = new AnimationTrack (keyseq, AnimationTrack.Alpha);
            var ctrl   = new AnimationController ();

            track1.SetController (ctrl);
            track2.SetController (ctrl);
            wld.AddAnimationTrack (track1);
            wld.AddAnimationTrack (track2);

            var query1 = wld.FindAll<KeyframeSequence> ();
            var query2 = wld.FindAll<AnimationController> ();

            Assert.Equal (1, query1.Length);
            Assert.Equal (keyseq, query1[0]);

            Assert.Equal (1, query2.Length);
            Assert.Equal (ctrl, query2[0]);
        }

        [Fact]
        public void TestDuplicate () {
            var cam = new Camera ();
            var bg  = new Background ();
            var wld = new World ();
            wld.SetActiveCamera (cam);
            wld.SetBackground (bg);
            wld.UserID = 100;

            var dup = (World)wld.Duplicate ();

            Assert.Equal (null, dup.Parent);
            Assert.Equal (wld.ActiveCamera, dup.ActiveCamera);
            Assert.Equal (wld.Background, dup.Background);
            Assert.Equal (wld.UserID, dup.UserID);
        }
    }
}
